package com.youdoneed.user.user;

import com.youdoneed.base.application.AppException;
import com.youdoneed.base.application.ResultMessage;
import com.youdoneed.base.common.AESEncryptor;
import com.youdoneed.base.common.JWTUtils;
import com.youdoneed.base.pagination.Page;
import com.youdoneed.base.pagination.Paging;
import com.youdoneed.user.consts.UserConst;
import com.youdoneed.user.model.User;
import com.youdoneed.user.vo.ContactUser;
import com.youdoneed.user.vo.NearbyUserParam;
import com.youdoneed.user.vo.UserBasicInfo;
import com.youdoneed.user.vo.UserShow;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author Ewing
 * @since 2017-04-21
 **/
@RestController
@RequestMapping("/user")
@Api(description = "用户")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 根据UserId获取用户。
     */
    @ApiOperation("根据UserId获取用户")
    @RequestMapping(value = "/getUser", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<User> getUser(String userId) {
        return new ResultMessage<>(userService.getUser(userId));
    }

    /**
     * 根据多个UserId获取用户。
     */
    @ApiOperation("根据多个UserId获取用户")
    @RequestMapping(value = "/getUsers", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<List<User>> getUsers(String[] userIds) {
        return new ResultMessage<>(userService.getUsers(userIds));
    }

    /**
     * 根据Token获取当前登陆的用户。
     */
    @ApiOperation("根据Token获取当前登陆的用户")
    @RequestMapping(value = "/currentUser", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<User> currentUser(@RequestHeader(UserConst.TOKEN_KEY) String token) {
        String userId = JWTUtils.getTokenUserId(token);
        return new ResultMessage<>(userService.getUser(userId));
    }

    /**
     * 根据手机号查询用户。
     */
    @ApiOperation("根据手机号查询用户")
    @RequestMapping(value = "/findByPhoneNo", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<User> findByPhoneNo(String phoneNo) {
        return new ResultMessage<>(userService.getUserByPhoneNo(phoneNo));
    }

    /**
     * 根据手机号查询用户，支持多个手机号。
     */
    @ApiOperation("根据多个手机号查询用户")
    @RequestMapping(value = "/findByPhoneNos", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<List<User>> findByPhoneNos(@RequestBody String[] phoneNos) {
        return new ResultMessage<>(userService.getUserByPhoneNos(phoneNos));
    }

    /**
     * 短信验证码登陆或注册。
     */
    @ApiOperation("手机号注册或登陆并生成Token，如果是新用户返回code为2")
    @RequestMapping(value = "/phoneNoLogin", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<String> phoneNoLogin(@ApiParam("电话号码") @RequestParam String phoneNo,
                                              @ApiParam("短信验证码") @RequestParam String code,
                                              @ApiParam("国家编号") @RequestParam String nation,
                                              @ApiParam("头像url") @RequestParam(required = false) String imgUrl) {
        if (!StringUtils.hasText(phoneNo) || !StringUtils.hasText(code)) {
            throw new AppException("PhoneNumberAndVerificationCodeCanNotBeEmpty");
        }

        // 验证短信验证码是否匹配
        String codeKey = "loginCode" + nation + phoneNo;
        String loginCode = redisTemplate.opsForValue().get(codeKey);
        if (loginCode == null || !code.equalsIgnoreCase(DigestUtils.md5DigestAsHex(loginCode.getBytes()))) {
            // 尝试用户名密码登陆
            User user = userService.getUserByPhoneNo(phoneNo);
            if (user == null || !StringUtils.hasText(user.getPassword())
                    || !user.getPassword().equals(code)) {
                throw new AppException("PhoneNumberOrVerificationCodeIsIncorrect");
            }
        }

        // 验证通过，开始登陆
        ResultMessage<User> message = userService.phoneNoLoginOrRegister(phoneNo, nation, imgUrl);

        // 登陆成功，添加userId到Token
        String token = JWTUtils.generateToken(UserConst.USER_ID_KEY, message.getData().getUserId());
        return new ResultMessage<>(token).setCode(message.getCode());
    }

    /**
     * 查找用户并分页。
     */
    @RequestMapping(value = "/findUsers", method = {RequestMethod.GET, RequestMethod.POST})
    @ApiOperation("查找用户并分页（无须统计总数时count传false可提高查询效率）")
    public ResultMessage<Page<User>> findUsers(Paging paging, String name, String phoneNo) {
        return new ResultMessage<>(userService.findUsers(paging, name, phoneNo));
    }

    /**
     * 查找其他用户。
     */
    @RequestMapping(value = "/findOthers", method = {RequestMethod.GET, RequestMethod.POST})
    @ApiOperation("查找其他用户")
    public ResultMessage<List<UserShow>> findOthers(
            @RequestHeader(UserConst.TOKEN_KEY) String token, Paging paging, String name) {
        String userId = JWTUtils.getTokenUserId(token);
        return new ResultMessage<>(userService.findOthers(userId, paging, name));
    }

    /**
     * 用户修改自己的基本信息。
     */
    @ApiOperation("用户修改自己的基本信息（只传需要修改的参数）")
    @RequestMapping(value = "/setUserBasicInfo", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage setUserBasicInfo(
            @RequestHeader(UserConst.TOKEN_KEY) String token, UserBasicInfo userParam) {
        String userId = JWTUtils.getTokenUserId(token);
        userParam.setUserId(userId); // 只能修改自己的信息
        userService.setUserBasicInfo(userParam);
        return new ResultMessage();
    }

    /**
     * 附近的用户。
     */
    @ApiOperation("附近的用户")
    @RequestMapping(value = "/nearbyUsers", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<List<UserShow>> nearbyUsers(
            @RequestHeader(UserConst.TOKEN_KEY) String token, Paging paging, NearbyUserParam nearby) {
        String userId = JWTUtils.getTokenUserId(token);
        return new ResultMessage<>(userService.nearbyUsers(paging, userId, nearby));
    }

    /**
     * 获取用户展示信息。
     */
    @ApiOperation("获取用户展示信息")
    @RequestMapping(value = "/getUserShow", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<UserShow> getUserShow(String userId) {
        return new ResultMessage<>(userService.getUserShow(userId));
    }

    /**
     * 查询给定的ID范围内的用户。
     */
    @ApiOperation("查询给定的ID范围内的用户")
    @RequestMapping(value = "/findInUserIds", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<List<UserBasicInfo>> findInUserIds(String[] userIds, String name) {
        return new ResultMessage<>(userService.findInUserIds(userIds, name));
    }

    /**
     * 短信邀请好友注册。
     */
    @ApiOperation("短信邀请好友注册")
    @RequestMapping(value = "/inviteUser", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage inviteUser(
            @RequestHeader(UserConst.TOKEN_KEY) String token, String otherPhoneNo) {
        String userId = JWTUtils.getTokenUserId(token);
        userService.inviteUser(userId, otherPhoneNo);
        return new ResultMessage();
    }

    /**
     * 判断用户的通讯录的号码今天是否已邀请。
     */
    @ApiOperation("判断用户的通讯录的号码今天是否已邀请")
    @RequestMapping(value = "/hasInvitedToday", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage<List<String>> hasInvitedToday(
            @RequestHeader(UserConst.TOKEN_KEY) String token, @RequestBody String[] otherPhoneNos) {
        String userId = JWTUtils.getTokenUserId(token);
        List<String> invitedPhoneNos = userService.hasInvitedToday(userId, otherPhoneNos);
        return new ResultMessage<>(invitedPhoneNos);
    }

    /**
     * 改变用户的统计信息。
     */
    @ApiOperation("改变用户的统计信息")
    @RequestMapping(value = "/changeStatistics", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultMessage changeStatistics(
            String userId, Integer totalArticleChange, Integer totalFriendChange) {
        userService.changeStatistics(userId, totalArticleChange, totalFriendChange);
        return new ResultMessage();
    }

    /**
     * 获取用户通讯录中已注册的用户。
     */
    @ApiOperation("获取用户通讯录中已注册的用户")
    @RequestMapping(value = "/getContactUsers", method = RequestMethod.POST)
    public ResultMessage<List<ContactUser>> getContactUsers(
            @RequestHeader(UserConst.TOKEN_KEY) String token) {
        String userId = JWTUtils.getTokenUserId(token);
        return new ResultMessage<>(userService.getContactUsers(userId));
    }

}
